from django.utils.deprecation import MiddlewareMixin
from django.http import JsonResponse
import traceback
import logging
import json

from .base import HomeException
from teat_demo.conf.default import DEBUG

# 判断是否安装了sentry 如果安装的话就调用，否者做特殊处理
# 关于sentry 的配置需要添加通知的方式，关于通知的方式可以通过文档查询即可

try:
    # 收集异常，可以通过UI来查看和搜索异常的信息
    from raven.contrib.django.raven_compat.models import sentry_exception_handler
except ImportError:
    sentry_exception_handler = None


logger = logging.getLogger('teat_demo')


class AppExceptionMiddleware(MiddlewareMixin):

    def process_exception(self,request,exception):
        """
        处理错误的中间件统一处理
        """


        if isinstance(exception, HomeException):
            # 打印错误日志，
            # 错误日志的构建
            # 错误的详情，可以通过traceback.format_exc()里面获取
            # 错误代码 error_code==属于exception属性==>exception
            # 错误详情 message  同上
            # 错误的方法对应的参数 同上  都是属于exception

            # 构造的格式如:"""主动抛出的异常，具体异常详情->[%s] status_code->[%s] &""" 
            # """ client_messsage->[%s] & args->[%s] """ 对应上方的参数格式
            logger.warning(
                (u"""主动捕获的错误详情->[%s] status_code->[%s] &"""
                """ client_message->[%s] & args->[%s] """
                 ) % (
                     traceback.format_exc(),exception.status_code,
                     exception.message,exception.args
                 )
            )
            # import pdb
            # pdb.set_trace() 

            response = JsonResponse({
                'status_code':exception.error_code,
                'message':exception.message
            })
            response.status_code = exception.error_code // 100
            return response
        
        # 没有捕获的异常处理
        # 首先判断环境是否是DEBUG 环境，如果是的话 就直接return None 不做任何处理
        # 判断环境的来源 通过settings.INFO 来获取

        # 没有捕获异常的日志构建格式
        # 异常详情 traceback.format_exc()
        # 请求的URL request.path
        # 请求的方法 request.method,
        # 请求的参数 json.dumps(getattr(request,request.method,None)) # 转成string

        logger.warning(
                (u"""主动捕获的错误详情->[%s] url->[%s] &"""
                """ method->[%s] & args->[%s] """
                 ) % (
                     traceback.format_exc(),request.path,
                     request.method,json.dumps(getattr(request,request.method,None))
                 )
            )
        if DEBUG:
            return None
        # 构造返回的提示
        response = JsonResponse({
            'status_code': 50000,
            'message': u'系统异常请联系管理员',
            'dir':dir(exception),
            'cookie':request.COOKIES.get('name'),
            'exc':traceback.format_exc()
        })
        response.status_code = 500

        response.set_cookie('name',123123)

        print(traceback.format_exc())
        # 是否使用异常通知 sentry <可以通过email和钉钉的通知>
        # 使用的方法可以通过sentry的官方文档来查看

        # 实现的方法
        
        if sentry_exception_handler is not None:
                sentry_exception_handler(request=request) # 这里的request 对应客户端的请求
        
        return response